#include "stdafx.h"
#include "CameraManager.h"


CameraManager::CameraManager()
{
	mCamera = Ogre::Root::getSingleton().getSceneManager("Main")->getCamera("PlayerCam");
	mConsole = Console::getSingletonPtr();

	Ogre::Root::getSingleton().addFrameListener(this);

	foward = false;
	back = false;
	right = false;
	left = false;

	vel = 50.0;

	mode = FREE_LOOK;
	dest = Ogre::Vector3::ZERO;

	targetDist = 250;
	floorDist = 200;


}

void CameraManager::setCameraVel(const float nVel)
{
	vel = nVel;
}

float CameraManager::getCameraVel()
{
	return vel;
}

void CameraManager::setCameraMode(const int cmode)
{
	mode = cmode;

	if(mode==FIRST_PERSON)
		targetDist = 0;

	if(mTarget == 0)
		mode = FREE_LOOK;
}

int CameraManager::getCameraMode()
{
	return mode;
}


bool CameraManager::frameRenderingQueued(const Ogre::FrameEvent& evt){

	if(foward || back || right || left){

		if(foward)dest += mCamera->getDirection();
		if(back)dest -= mCamera->getDirection();
		if(left)dest -= mCamera->getRight();
		if(right)dest += mCamera->getRight();

		dest.normalise();
		mCamera->move(dest*evt.timeSinceLastFrame*vel);
	}


	return true;

}

bool CameraManager::keyPressed( const OIS::KeyEvent &arg ){

	if(mode==FREE_LOOK){
		switch(arg.key){
		case OIS::KC_W: foward=true; break;
		case OIS::KC_S: back=true; break;
		case OIS::KC_A: left=true; break;
		case OIS::KC_D: right=true; break;

		}
	}
	return true;
}
bool CameraManager::keyReleased( const OIS::KeyEvent &arg ){

	if(mode==FREE_LOOK){
		switch(arg.key){
		case OIS::KC_W: foward=false; break;
		case OIS::KC_S: back=false; break;
		case OIS::KC_A: left=false; break;
		case OIS::KC_D: right=false; break;
		}
	}
	if(!foward && !back && !right && !left)
		dest = Ogre::Vector3::ZERO;

	return true;
}

bool CameraManager::mouseMoved( const OIS::MouseEvent &arg ){



	if(mode == THIRD_PERSON){

		float xPos;
		float zPos;
		Ogre::Real radPitch;

		bool camPitch = false;

		radPitch = mCamera->getDirection().y;



		mCamera->setPosition(mTarget->_getDerivedPosition()); 

		mCamera->yaw(Ogre::Degree(-arg.state.X.rel * 0.15f));

		if(radPitch  > -0.90 && radPitch < 0.10)
			camPitch = true;
		else
			if(radPitch >= -0.90 && Ogre::Degree(-arg.state.Y.rel * 0.15f).valueDegrees() <= 0.01)
				camPitch = true;
			else if(radPitch <= 0.10 && Ogre::Degree(-arg.state.Y.rel * 0.15f).valueDegrees() >= 0.01)
				camPitch = true;

		if(camPitch == true)
			mCamera->pitch(Ogre::Degree(-arg.state.Y.rel * 0.15f));


		xPos = mTarget->getPosition().x + targetDist * std::cos(3.1415 / 2);
		zPos = mTarget->getPosition().z + targetDist * std::sin(3.1415 / 2);

		mCamera->moveRelative(Ogre::Vector3(xPos, 50, zPos));


	}else if(mode == FIRST_PERSON){
	
		float xPos;
		float zPos;
		Ogre::Real radPitch;

		bool camPitch = false;

		radPitch = mCamera->getDirection().y;

		mCamera->setPosition(mTarget->_getDerivedPosition()); 

		mCamera->yaw(Ogre::Degree(-arg.state.X.rel * 0.15f));

		if(radPitch  > -0.80 && radPitch < 0.9)
			camPitch = true;
		else
			if(radPitch >= -0.80 && Ogre::Degree(-arg.state.Y.rel * 0.15f).valueDegrees() <= 0.01)
				camPitch = true;
			else if(radPitch <= 0.90 && Ogre::Degree(-arg.state.Y.rel * 0.15f).valueDegrees() >= 0.01)
				camPitch = true;

		if(camPitch == true)
			mCamera->pitch(Ogre::Degree(-arg.state.Y.rel * 0.15f));


		xPos = mTarget->getPosition().x + targetDist * std::cos(3.1415 / 2);
		zPos = mTarget->getPosition().z + targetDist * std::sin(3.1415 / 2);

		mCamera->moveRelative(Ogre::Vector3(xPos, floorDist, zPos));
	
	}else{

		mCamera->yaw(Ogre::Degree(-arg.state.X.rel * 0.15f));
		mCamera->pitch(Ogre::Degree(-arg.state.Y.rel * 0.15f));

	}


	return true;
}
bool CameraManager::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){
	return true;
}
bool CameraManager::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){

	return true;
}

void CameraManager::setTarget(Ogre::SceneNode *node)
{
	mTarget = node;


	if(mode==THIRD_PERSON || mode==FIRST_PERSON)
	{
		float xPos;
		float zPos;

		mCamera->setPosition(mTarget->_getDerivedPosition()); 

		xPos = mTarget->getPosition().x + targetDist * std::cos(3.1415 / 2);
		zPos = mTarget->getPosition().z + targetDist * std::sin(3.1415 / 2);

		mCamera->moveRelative(Ogre::Vector3(xPos, 100, zPos));

	}


}

void CameraManager::setTargetDist(const float dist)
{
	if(mode==THIRD_PERSON)
		targetDist = dist;
}

float CameraManager::getTargetDist()
{
	return targetDist;
}

void CameraManager::setFloorDist(const int floorDist)
{
	this->floorDist = floorDist;
}

int CameraManager::getFloorDist()
{
	return this->floorDist;
}